﻿/* 7.*** Write a program that finds the largest area of equal neighbor elements in a rectangular matrix and prints its size. */

// We'll solve more general task for 3-dimensional array of strings.

using System;
using System.Collections.Generic;

public class LargestAreaOfEqualNeighbors
{
    public static int heght;
    public static int width;
    public static int depth;
    public static string[][][] space;

    public static List<List<int>> discover = new List<List<int>>();

    public static int counterOfMaxLenght = 0;
    public static int maxLength = 0;
    public static int currentLength = 0;

    public static int news = 0;
    public static string element;

    public static void Main()
    {
        DataInput();
        Claculation();
        PrintResult();
    }

    public static void DataInput()
    {
        do
        {
            Console.Clear();
            Console.Write("\n\nHeight: ");
            if (int.TryParse(Console.ReadLine(), out heght))
            {
                do
                {
                    Console.Clear();
                    Console.Write("\n\nHeight: {0}\nWidth: ", heght);
                    if (int.TryParse(Console.ReadLine(), out width))
                    {
                        do
                        {
                            Console.Clear();
                            Console.Write("\n\nHeight: {0}\nWidth: {1}\nDepth: ", heght, width);
                            if ((int.TryParse(Console.ReadLine(), out depth)) && (1 <= depth))
                                break;
                        } while (true);

                        break;
                    }
                } while (true);

                break;
            }
        } while (true);

        space = new string[heght][][];
        for (int i = 0; i < heght; i++)
        {
            space[i] = new string[width][];
            for (int j = 0; j < width; j++)
                space[i][j] = new string[depth];
        }

        Console.WriteLine("\n\nPlease, enter the space:\n");
        for (int k = 0; k < depth; k++)
        {
            for (int i = 0; i < heght; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    Console.Write("[{0}][{1}][{2}] = ", i, j, k);
                    space[i][j][k] = Console.ReadLine();
                }

                Console.WriteLine();
            }

            Console.WriteLine("");
        }

        discover.Add(new List<int>(0));
        discover.Add(new List<int>(1));
        discover.Add(new List<int>(2));
    }

    public static void Claculation()
    {
        for (int i = 0; i < heght; i++)
        {
            for (int j = 0; j < width; j++)
            {
                for (int k = 0; k < depth; k++)
                {
                    if (space[i][j][k] == null)
                        continue;

                    element = space[i][j][k];
                    space[i][j][k] = null;

                    discover[0].Clear();
                    discover[0].Add(i);
                    discover[1].Clear();
                    discover[1].Add(j);
                    discover[2].Clear();
                    discover[2].Add(k);

                    news = 1;

                    currentLength = 1;

                    while (news > 0)
                    {
                        CheckAllNeighbours();

                        discover[0].RemoveRange(0, news);
                        discover[1].RemoveRange(0, news);
                        discover[2].RemoveRange(0, news);

                        news = discover[0].Count;
                    }

                    if (maxLength < currentLength)
                    {
                        maxLength = currentLength;
                        counterOfMaxLenght = 1;
                    }
                    else if (maxLength == currentLength)
                        counterOfMaxLenght++;
                }
            }
        }
    }

    public static void CheckAllNeighbours()
    {
        for (int m = 0; m < news; m++)
        {
            CheckNeighbour(discover[0][m] - 1, discover[1][m] - 1, discover[2][m]);
            CheckNeighbour(discover[0][m] - 1, discover[1][m], discover[2][m]);
            CheckNeighbour(discover[0][m] - 1, discover[1][m] + 1, discover[2][m]);
            CheckNeighbour(discover[0][m], discover[1][m] - 1, discover[2][m]);
            CheckNeighbour(discover[0][m], discover[1][m] + 1, discover[2][m]);
            CheckNeighbour(discover[0][m] + 1, discover[1][m] - 1, discover[2][m]);
            CheckNeighbour(discover[0][m] + 1, discover[1][m], discover[2][m]);
            CheckNeighbour(discover[0][m] + 1, discover[1][m] + 1, discover[2][m]);

            CheckNeighbour(discover[0][m] - 1, discover[1][m] - 1, discover[2][m] - 1);
            CheckNeighbour(discover[0][m] - 1, discover[1][m], discover[2][m] - 1);
            CheckNeighbour(discover[0][m] - 1, discover[1][m] + 1, discover[2][m] - 1);
            CheckNeighbour(discover[0][m], discover[1][m] - 1, discover[2][m] - 1);
            CheckNeighbour(discover[0][m], discover[1][m], discover[2][m] - 1);
            CheckNeighbour(discover[0][m], discover[1][m] + 1, discover[2][m] - 1);
            CheckNeighbour(discover[0][m] + 1, discover[1][m] - 1, discover[2][m] - 1);
            CheckNeighbour(discover[0][m] + 1, discover[1][m], discover[2][m] - 1);
            CheckNeighbour(discover[0][m] + 1, discover[1][m] + 1, discover[2][m] - 1);

            CheckNeighbour(discover[0][m] - 1, discover[1][m] - 1, discover[2][m] + 1);
            CheckNeighbour(discover[0][m] - 1, discover[1][m], discover[2][m] + 1);
            CheckNeighbour(discover[0][m] - 1, discover[1][m] + 1, discover[2][m] + 1);
            CheckNeighbour(discover[0][m], discover[1][m] - 1, discover[2][m] + 1);
            CheckNeighbour(discover[0][m], discover[1][m], discover[2][m] + 1);
            CheckNeighbour(discover[0][m], discover[1][m] + 1, discover[2][m] + 1);
            CheckNeighbour(discover[0][m] + 1, discover[1][m] - 1, discover[2][m] + 1);
            CheckNeighbour(discover[0][m] + 1, discover[1][m], discover[2][m] + 1);
            CheckNeighbour(discover[0][m] + 1, discover[1][m] + 1, discover[2][m] + 1);
        }
    }

    public static void CheckNeighbour(int p, int q, int s)
    {
        if ((0 <= p) && (p < heght) && (0 <= q) && (q < width) && (0 <= s) && (s < depth) && (space[p][q][s] == element))
        {
            space[p][q][s] = null;
            discover[0].Add(p);
            discover[1].Add(q);
            discover[2].Add(s);
            currentLength++;
        }
    }

    public static void PrintResult()
    {
        if (counterOfMaxLenght > 1)
            Console.WriteLine("The lenght of one of all {0} largest areas of equal neighbors is {1}.\n", counterOfMaxLenght, maxLength);
        else
            Console.WriteLine("The lenght of the unique largest area of equal neighbors is {0}.\n", maxLength);
    }
}